import json
import re
import threading
import traceback
from functools import wraps
from time import sleep
import time

from Service.MyLogger import MyLogger
import os,logging,sqlite3

from Utils import DirUtil, RecordUtil

logFileName =  os.path.basename(__file__).split(".")[0]
from Statistics.COMMON import commonLogger
log = commonLogger # MyLogger(r"./Logs/%s.log" % (logFileName), logging.DEBUG, logging.DEBUG)

def ShowTimeCost(a_func,cd=-5):
    print(cd)
    @wraps(a_func)
    def wrapTheFunction(*args, **kwargs):
        t0 = time.time()
        res = a_func(*args, **kwargs)
        t9 = time.time()
        log.info(a_func.__name__, "timeCost:", round(t9 - t0, 2))
        return res

    return wrapTheFunction

def TaskChain(a_func):
    @wraps(a_func)
    def wrapTheFunction(*args, **kwargs):
        print("args:",args)
        print("kwargs:",kwargs)
        try:
            res = a_func(*args, **kwargs)
        except:
            res = "task error: "+traceback.format_exc()
        print(res)
        # args[0].append(res)
        if 'chainLog' in kwargs:
            kwargs['chainLog'].append({a_func.__name__: res})
        return res
    return wrapTheFunction
def RecordAction(a_func):
    @wraps(a_func)
    def wrapTheFunction(*args, **kwargs):
        if str(args[1].__class__)=="<class 'uiautomator2.Device'>":
            RecordUtil.recordAction(a_func.__name__,args[1].serial,args)
            log.info(f"funcName:{a_func.__name__}, serial:{args[1].serial}, args:{args[2:]}")
        try:
            res = a_func(*args, **kwargs)
        except:
            res = "task error: "+traceback.format_exc()
        # log.info("res@Record:",res)
        return res
    return wrapTheFunction
def RetryIfIs(countDown=3, slpSeconds=5, retryIfIs=None):
    def RetryB1(a_func):
        @wraps(a_func)
        def wrapTheFunction(*args, **kwargs):
            for i in range(countDown):
                try:
                    res = a_func(*args, **kwargs)
                    if res == retryIfIs:
                        print("Not expected I", "countDown:", countDown-i)
                        sleep(slpSeconds)
                    else:
                        return res
                except:
                    log.info("yzlog traceback RetryIfIs:", traceback.format_exc())
                    print("Abnormal", "countDown:", countDown-i)
                    sleep(slpSeconds)
            return None
        return wrapTheFunction
    return RetryB1
def RetryIfNot(countDown=3, slpSeconds=5, retryIfNot=None):
    def RetryB1(a_func):
        @wraps(a_func)
        def wrapTheFunction(*args, **kwargs):
            for i in range(countDown):
                try:
                    res = a_func(*args, **kwargs)
                    if res != retryIfNot:
                        print("Not expected", "countDown:", countDown - i)
                        sleep(slpSeconds)
                    else:
                        return res
                except:
                    log.info("yzlog traceback RetryIfNot:", traceback.format_exc())
                    print("Abnormal", "countDown:", countDown-i)
                    sleep(slpSeconds)
            return None
        return wrapTheFunction
    return RetryB1

def TryExcept2(returnDefault=None):
    def B1(a_func):
        @wraps(a_func)
        def wrapTheFunction(*args, **kwargs):
            try:
                res = a_func(*args, **kwargs)
                return res
            except:
                log.info("yzlog traceback TryExcept:", traceback.format_exc())
                return returnDefault

        return wrapTheFunction
    return B1
def TryExcept(a_func):
    @wraps(a_func)
    def wrapTheFunction(*args, **kwargs):
        try:
            res = a_func(*args, **kwargs)
            return res
        except:
            log.info("yzlog traceback TryExcept:", traceback.format_exc())
            return None
    return wrapTheFunction
def TryExceptWithCustomMsg(errorMsg=None,returnDefault=None):
    def B1(a_func):
        @wraps(a_func)
        def wrapTheFunction(*args, **kwargs):
            try:
                res = a_func(*args, **kwargs)
                return res
            except:
                log.info("yzlog traceback TryExcept:", traceback.format_exc())
                if errorMsg is not None:
                    log.info("yzlog TryExcept errorMsg:", errorMsg)
                return returnDefault
        return wrapTheFunction
    return B1
def Async(a_func):
    @wraps(a_func)
    def wrapTheFunction(*args, **kwargs):
        thread30 = threading.Thread(name='t30', target=a_func, args=(*args,), daemon=True) # kwargs=(**kwargs,),
        thread30.start()
        # 最多等thread30在5秒内执行完毕,超时的话就强制终止thread30线程了,也可用time.sleep来固定等它5秒
        thread30.join(86400)
    return wrapTheFunction
def AsyncNoJoin(a_func):
    @wraps(a_func)
    def wrapTheFunction(*args, **kwargs):
        thread31 = threading.Thread(name='t31', target=a_func, args=(*args,), daemon=True)  # kwargs=(**kwargs,),
        thread31.start()
    return wrapTheFunction

def CheckPath(pathArr=[]):
    def CheckPathInner(a_func):
        @wraps(a_func)
        def wrapTheFunction(*args, **kwargs):
            # log.info("*args:", *args)
            # log.info("**kwargs:", **kwargs)
            # log.info("kwargs:", kwargs)
            # for k,vv in kwargs.items():
            #     log.info(k,vv)
            for i in range(len(pathArr)):
                pathFile = kwargs.get(pathArr[i])
                if None!=pathFile:
                    path,fileName = os.path.split(pathFile)
                    # log.info(pathArr[i],path,type(path),os.path.isdir(path))
                    if not os.path.exists(path):
                        os.makedirs(path)
            res = a_func(*args, **kwargs)
            return res
        return wrapTheFunction
    return CheckPathInner
def RecordSthToTxt():
    pass
# @TryPassParam
# def testPassParam(param):
#     log.info("yzlog param:", param)
#     print("executed")
#     return 55

# Test:

if __name__ == '__main__':
    pass